﻿/***********************************************************************************************
 * 
 * ProjectName: WMSSoft.WinKStart
 * 
 * Description: Render Items to Listbox
 * 
 * Created:     10.11.2013
 * 
 * Author:      matthias wagler - matthias@WMSSoft.de
 * 
 * Copyright:   Copyright 2012 by WMSSoft.de
 * 
 * License:     GPLv3
 * 
 * History:     10.11.2013 - matthias wagler matthias@WMSSoft.de   -   Created
 * 
 **********************************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using WMSSoft.Lib.Basic;
using WMSSoft.Lib.WinKStart;
using WMSSoft.Lib.Enums;
using WMSSoft.Lib.Const;
using WMSSoft.Lib.WinKStart.Model.MenuConfig;

namespace WMSSoft.WinKStart.Lib
{
    public delegate void ItemSelectedEventHandler(Object Sender, cStartmenuItem Item);
    public delegate void SetBreadCrumbEventHandler(Object Sender, List<string> ItemNames, List<cStartmenuItem> Items);

    public class ItemRenderer
    {        
        private cStartmenuItem _RootItem = null;
        private cStartmenuItem _CurrentItem = null;
        private ListBox _DrawingBox = null;
        private Dictionary<int, cStartmenuItem> _VisibleItems = null; 
        private bool _CanAddToFavorites;
        private bool _CanRemoveFavorite;
        private bool _CanNavigate;
        private bool _CanShowContextmenu;
        int _RunCounter = 0;
        private cRegion _Settings = null;

        public event ItemSelectedEventHandler SelectionChanged;
        public event SetBreadCrumbEventHandler SetBreadCrumb;
        public event WMSSoft.Lib.Shell.FavoriteEventArgs AddFavorite;
        public event WMSSoft.Lib.Shell.FavoriteEventArgs RemoveFavorite;

        public ItemRenderer(ListBox Box, cStartmenuItem Root, cRegion Tabpage = null)
        {
            _DrawingBox = Box;
            _VisibleItems = new Dictionary<int, cStartmenuItem>();
            _CanNavigate = true;
            _CanShowContextmenu = true;
            _Settings = Tabpage;    
            
            _RootItem = Root;            
        }

        #region Properties

        /// <summary>
        /// if true and user shows the contextmenu for a item then in contextmenu is a menuitem named "add favorite"
        /// </summary>
        public bool CanAddToFavorites
        {
            get { return _CanAddToFavorites; }
            set { _CanAddToFavorites = value; }
        }

        //if true an user shows the contextmenu for an item then in contextmenu is a item named "remove from favorite"
        public bool CanRemoveFavorite
        {
            get { return _CanRemoveFavorite; }
            set { _CanRemoveFavorite = value;  }
        }

        public bool CanNavigate
        {
            get { return _CanNavigate; }
            set { _CanNavigate = value; }
        }

        public bool CanShowContextmenu
        {
            get { return _CanShowContextmenu; }
            set { _CanShowContextmenu = value; }
        }

        #endregion

        #region Public Methods
        /// <summary>
        /// This Method Render the Item of the Parent from CurrentRoot Item
        /// </summary>
        public void GoLevelUp()
        {
            if (_CurrentItem != null && _CurrentItem.Parent != null && _CurrentItem != _RootItem && _CanNavigate == true)
            {
                List<string> myParentViewName = new List<string>();
                myParentViewName.Add(_CurrentItem.Parent.FolderMenuPath);

                cStartmenuItem myParent = (cStartmenuItem)_CurrentItem.Parent;

                List<cStartmenuItem> myParentObjects = new List<cStartmenuItem>();

                do
                {
                    myParentObjects.Add(myParent);

                    if (myParent != _RootItem)
                    {
                        myParent = (cStartmenuItem)myParent.Parent;
                    }
                    else myParent = null;
                } while (myParent != null);              

                if (SetBreadCrumb != null) SetBreadCrumb(this, myParentViewName, myParentObjects);

                RenderItems((cStartmenuItem)_CurrentItem.Parent);
            }
        }

        /// <summary>
        /// Set the Current selected Item to Startmenus - Top Item
        /// </summary>
        public void GoRoot(string Datasource, string Filter, ListBox ContentList)
        {
            cStartmenuItem oRootItem = null;
            if (Datasource.Length > 0 && Filter.Length > 0)
            {
                oRootItem = cMenuConfigReader.DataSources.GetData(Datasource, Filter);
            }

            if (oRootItem != null && _CanNavigate == true)
            {
                List<cStartmenuItem> myParentObjects = new List<cStartmenuItem>();
                List<string> myParentViewName = new List<string>();
                myParentViewName.Add(oRootItem.ViewName);

                myParentObjects.Add(oRootItem);

                if (_Settings.RendererMethode == eRenderType.Groups)
                {
                    if (SetBreadCrumb != null) SetBreadCrumb(this, myParentViewName, myParentObjects);
                    SetRendererBreadCrumb(Datasource, Filter,
                                          ((MinimizeablePanel)((Grid)ContentList.Parent).Parent),
                                          oRootItem);
                }

                RenderItems(oRootItem, ContentList, _Settings.RendererMethode);
            }
        }

        /// <summary>
        /// Go one or more Levels up to the given Root
        /// </summary>
        /// <param name="NewRoot">Root to render items from</param>
        public void GoLevelUp(cStartmenuItem NewRoot)
        {
            if (NewRoot != null && _CanNavigate == true) // && NewRoot != _RootItem)
            {
                List<string> myParentViewName = new List<string>();
                myParentViewName.Add(NewRoot.FolderMenuPath);

                cStartmenuItem myParent = NewRoot;

                List<cStartmenuItem> myParentObjects = new List<cStartmenuItem>();

                do
                {
                    myParentObjects.Add(myParent);

                    if (myParent != _RootItem)
                    {
                        myParent = (cStartmenuItem)myParent.Parent;
                    }
                    else myParent = null;
                } while (myParent != null);

                if (SetBreadCrumb != null) SetBreadCrumb(this, myParentViewName, myParentObjects);

                RenderItems(NewRoot);
            }
        }

        /// <summary>
        /// This Methode add the ListItems defined in Parent to the Listbox
        /// </summary>
        /// <param name="Parent"></param>
        public void RenderItems(cStartmenuItem Parent, System.Windows.Controls.ListBox ContentList = null, eRenderType RenderMethode = eRenderType.Groups)
        {
            try
            {
                bool bCanRun = true;
                System.Windows.Controls.ListBox ContentListbox = _DrawingBox;
                if (ContentList != null) ContentListbox = ContentList;

                if (Parent != null && ContentListbox != null && _VisibleItems != null)
                {
                    _VisibleItems.Clear();
                    ContentListbox.Items.Clear();
                    _CurrentItem = Parent;
                    WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel PanelSettings = null;
                    bool bSorting = false;
                    if (RenderMethode == eRenderType.Groups)
                    {
                        MinimizeablePanel oParentPanel = ((MinimizeablePanel)((Grid)ContentListbox.Parent).Parent);
                        PanelSettings = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)oParentPanel.Tag);
                        bSorting = PanelSettings.SortItems;
                    }
                    else
                    {
                        bSorting = true;
                    }

                    //Apply Style to Listbox
                    cStyleChanger.ApplyStyleToRegionData(ContentListbox, _Settings.Name);

                    if (bSorting == true)
                        _CurrentItem.FolderItemKeys.Sort();
                    string[] oFilterItemKeys = new string[_CurrentItem.FolderItemKeys.Count];
                    List<string> myFolderItem = _CurrentItem.FolderItemKeys;//.CopyTo(oFilterItemKeys);
                    _CurrentItem.FolderItemKeys.CopyTo(oFilterItemKeys);
                    if (bSorting == true)
                        _CurrentItem.LinkItemList.Sort();

                    List<string> myLinkItems = _CurrentItem.LinkItemList;

                    //Render Folder - Items
                    foreach (string Item in oFilterItemKeys)
                    {
                        cStartmenuItem tmpItem = (cStartmenuItem)_CurrentItem.ChildItems[_CurrentItem.FolderDisplayNames[Item]];
                        AddItemToListBox(tmpItem, ContentListbox, _VisibleItems);

                    }

                    string[] oLinkItemKeys = new string[_CurrentItem.LinkItemList.Count];
                    _CurrentItem.LinkItemList.CopyTo(oLinkItemKeys);
                    //Render  Link - Items
                    foreach (string Item in oLinkItemKeys)
                    {
                        //it is needed to switch between link- und label Items
                        if (((cStartmenuItem)_CurrentItem.ChildItems[_CurrentItem.LinkDisplayNames[Item]]).ItemType == eItemType.Link)
                        {
                            cStartmenuItem tmpItem = (cStartmenuItem)_CurrentItem.ChildItems[_CurrentItem.LinkDisplayNames[Item]];

                            bool bIsFilePath = false;

                            if (tmpItem.LinkFilename.Length > 0)
                            {
                                //TODO: this hack is not good, but for string how 
                                //"C:\Program Files\Microsoft Office\root\Client\AppVLP.exe" rundll32.exe shell32.dll,Control_RunDLL "C:\Program Files\Microsoft Office\root\Office16\MLCFG32.CPL" 
                                //necessary
                                try
                                {
                                    string stmpLinkPath = System.IO.Path.GetDirectoryName(tmpItem.LinkFilename);
                                    string stmpLinkFilename = System.IO.Path.GetFileName(tmpItem.LinkFilename);
                                    if (stmpLinkPath.Length > 0 && stmpLinkFilename.Length > 0) bIsFilePath = true;
                                }
                                catch
                                {
                                    bIsFilePath = false;
                                }
                            }
                            if (bIsFilePath == true && tmpItem.ContentType != eContentPanelContentType.SearchResultWeb)
                            {
                                if (System.IO.File.Exists(tmpItem.LinkFilename) == true)
                                {
                                    AddItemToListBox(tmpItem, ContentListbox, _VisibleItems);
                                }
                            } else 
                                AddItemToListBox(tmpItem, ContentListbox, _VisibleItems);
                            
                        }
                        else if (((cStartmenuItem)_CurrentItem.ChildItems[_CurrentItem.LinkDisplayNames[Item]]).ItemType == eItemType.Label)
                        {
                            //process label items
                            cStartmenuItem tmpItem = (cStartmenuItem)_CurrentItem.ChildItems[_CurrentItem.LinkDisplayNames[Item]];
                            AddLabelItemToListBox(tmpItem, ContentListbox);

                        }
                    }
                    

                    if (RenderMethode == eRenderType.Simple)
                    {
                        if (_Settings.CanNavigate)
                            SetRendererBreadCrumb(_Settings.DataSource, _CurrentItem.FolderMenuPath, null, _CurrentItem);
                    }
                    bCanRun = false;
                     
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Unable to render Menu to List!", Ex, true, EMessageTypes.Error);
            }
        }

        public void RenderGroupItems()
        {
            try
            {
                if (_Settings != null && _Settings.Panels.Panels.Count > 0)
                {
                    _DrawingBox.Items.Clear();
                    WMSSoft.WinKStart.MinimizeablePanel ChildPanel = null;
                    string GroupItemsKey = "";
                    string sDatasource = "";
                    string sFilter = "";
                    int iPanelsHeight = 0;

                    _DrawingBox.Padding = new Thickness(0, 0, 0, 0);
                    _DrawingBox.Margin = new Thickness(0, 0, 0, 0);

                    for (int iPanelCounter = 0; iPanelCounter < _Settings.Panels.Panels.Count; iPanelCounter++)
                    {
                        if (_Settings.Panels.Panels[iPanelCounter].DataSource.Length > 0 &&
                            _Settings.Panels.Panels[iPanelCounter].Filter.Length > 0)
                        {
                            try
                            {
                                sDatasource = _Settings.Panels.Panels[iPanelCounter].DataSource;
                                sFilter = _Settings.Panels.Panels[iPanelCounter].Filter;
                                

                                string PanelCaption = _Settings.Panels.Panels[iPanelCounter].Caption;
                                eContentPanelContentType ContentType = _Settings.Panels.Panels[iPanelCounter].ContentType;
                                
                                ChildPanel = new WMSSoft.WinKStart.MinimizeablePanel();
                                ChildPanel.Caption = WMSSoft.Lib.Basic.LanguageStrings.GetText(PanelCaption);
                                ChildPanel.ContentItemheight = cStyleChanger.GetPanelDataLineHeight(_Settings.Panels.Panels[iPanelCounter].PanelID);
                                ChildPanel.Tag = _Settings.Panels.Panels[iPanelCounter];


                                //Create Key to Access the Child Item for this Group
                                GroupItemsKey = _Settings.Panels.Panels[iPanelCounter].ContentType.ToString();

                                if (_Settings.Panels.Panels[iPanelCounter].PanelID.Length > 0) GroupItemsKey += "." + _Settings.Panels.Panels[iPanelCounter].PanelID;
                                if (_Settings.Panels.Panels[iPanelCounter].ItemType == eItemType.Folder) GroupItemsKey += "." + _Settings.Panels.Panels[iPanelCounter].ItemType.ToString();

                                //apply contentitem height
                                ChildPanel.HorizontalContentAlignment = HorizontalAlignment.Stretch;

                                int iRealVisibleItems = (int)_Settings.Panels.Panels[iPanelCounter].MaxViewedElements;
                                string sDataSourceName = ((string)StartMenuItemPrefix.STARTMENUITEM_PREFIX__DATASOURCEITEM_DATANAME + sDatasource).ToUpper();
                                //Get Render DataItems
                                cStartmenuItem tmpRenderItem = null;
                                if (_Settings.RendererMethode == eRenderType.Groups)
                                    tmpRenderItem = (cStartmenuItem)cMenuConfigReader.DataSources.GetData(sDatasource, sFilter);
                                else
                                    tmpRenderItem = (cStartmenuItem)cMenuConfigReader.DataSources.GetData(sDatasource, sFilter).Copy();
                                //how many Items are rendering
                                if (tmpRenderItem != null)
                                {
                                    if (tmpRenderItem.ChildItems.Count < (double)_Settings.Panels.Panels[iPanelCounter].MaxViewedElements)
                                        iRealVisibleItems = tmpRenderItem.ChildItems.Count;
                                }
                                //if here are no child items the render height for one item
                                if (iRealVisibleItems == 0)
                                {
                                    iRealVisibleItems = 1;
                                    ChildPanel.Height = _DrawingBox.Height-10;
                                }
                                else
                                    ChildPanel.Height = (double)Convert.ToInt32(ChildPanel.Header.Height) + (iRealVisibleItems * ChildPanel.ContentItemheight);

                                iPanelsHeight += ((int)ChildPanel.Height);

                                //Render ChildItems to Grouplistbox
                                if (tmpRenderItem != null)
                                {
                                    RenderItems(tmpRenderItem, ChildPanel.ListContent);
                                }
    
                                int itmpListItemsCount = ChildPanel.ListContent.Items.Count;

                                //Test, if we have invisible (not existing elements in filesystem)
                                if (itmpListItemsCount < iRealVisibleItems)
                                {
                                    //the list items height must be recalculated
                                    iPanelsHeight -= ((int)ChildPanel.Height);

                                    iRealVisibleItems = itmpListItemsCount;
                                    if (iRealVisibleItems == 0) iRealVisibleItems = 1;

                                    ChildPanel.Height = (double)Convert.ToInt32(ChildPanel.Header.Height) + (iRealVisibleItems * ChildPanel.ContentItemheight);
                                }

                                ChildPanel.Width = 250;

                                if (ChildPanel.ListContent.Items.Count > 0)
                                {
                                    _DrawingBox.Items.Add(ChildPanel);
                                }

                                //Apply Style to Panel
                                cStyleChanger.ApplyStyleToPanel(ChildPanel, _Settings.Panels.Panels[iPanelCounter].PanelID);
                                //Apply Header Style
                                cStyleChanger.ApplyStyleToPanelHeader(ChildPanel.Header, _Settings.Panels.Panels[iPanelCounter].PanelID);
                                //Apply Style to Data-ListBox
                                cStyleChanger.ApplyStyleToPanelData(ChildPanel.ListContent, _Settings.Panels.Panels[iPanelCounter].PanelID);
                            }
                            catch (Exception Ex)
                            {
                                CMessagelogging.AppendMessage("Unable to render Panel '" + _Settings.Panels.Panels[iPanelCounter].Caption + "' to List!", Ex, true, EMessageTypes.Error);
                            }
                        }
                    }
                    double dGroupsWidth = _DrawingBox.Width - 14;

                    if (_DrawingBox.Height - 20 < iPanelsHeight)
                        dGroupsWidth = _DrawingBox.Width - 32;

                    for (int iPanelCounter = 0; iPanelCounter < _DrawingBox.Items.Count; iPanelCounter++)
                    {
                        ((WMSSoft.WinKStart.MinimizeablePanel)_DrawingBox.Items[iPanelCounter]).Width = dGroupsWidth;
                    }
                }

            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Unable to render Menu Groups to List!", Ex, true, EMessageTypes.Error);
            }
        }


        #endregion

        #region Private Methods
        void OnSelectionChanged(object sender, cStartmenuItem SelectedItem) 
        {
            try
            {
                cStartmenuItem myItem = null;
                bool bCanNavigate = false;
                string sFilter = "";
                string sDatasource = "";

                if (_Settings.RendererMethode == eRenderType.Groups)
                {

                    bCanNavigate = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent).Tag).CanNavigate;
                    sFilter = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent).Tag).Filter;
                    sDatasource = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent).Tag).DataSource;


                    if (SelectedItem != null)
                    {
                        myItem = SelectedItem;
                    }
                    else
                    {
                        if (_VisibleItems != null && _DrawingBox != null && _DrawingBox.SelectedIndex > -1)
                        {

                            myItem = this._VisibleItems[_DrawingBox.SelectedIndex];

                            _DrawingBox.SelectedIndex = -1;
                        }
                    }
                    if (myItem != null)
                    {

                        if (myItem.ItemType == eItemType.Link)
                        {
                            if (SelectionChanged != null) SelectionChanged(this, myItem);
                            //GoLevelUp();
                            GoRoot(sDatasource, sFilter, ((ListBox)sender));
                        }
                        else if (myItem.ItemType == eItemType.Folder && _CanNavigate == true)
                        {


                            if (((ListBox)sender).Parent != null && ((Grid)((ListBox)sender).Parent).Parent != null &&
                                ((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent).Tag != null)
                            {
                                bCanNavigate = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent).Tag).CanNavigate;
                                sFilter = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent).Tag).Filter;
                                sDatasource = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent).Tag).DataSource;

                                if (bCanNavigate == true)
                                {

                                    List<string> myParentViewName = new List<string>();
                                    myParentViewName.Add(myItem.ViewName);
                                    myParentViewName.Add(myItem.Parent.FolderMenuPath);
                                    cStartmenuItem myParent = (cStartmenuItem)myItem.Parent;

                                    SetRendererBreadCrumb(sDatasource, myItem.FolderMenuPath,
                                                          ((MinimizeablePanel)((Grid)((ListBox)sender).Parent).Parent),
                                                          myItem);

                                    RenderItems(myItem, ((ListBox)sender));
                                }
                            }
                        }
                    }
                }
                else
                {
                    //TODO: setbreadcrumbs
                    myItem = SelectedItem;
                    switch (myItem.ItemType)
                    {
                        case eItemType.Folder:
                            if (_Settings.CanNavigate)
                            {
                                RenderItems(myItem, _DrawingBox, eRenderType.Simple);
                                SetRendererBreadCrumb(_Settings.DataSource, myItem.FolderMenuPath, null, myItem);
                            }
                            break;
                        case eItemType.Link:
                            if (SelectionChanged != null) SelectionChanged(this, myItem);
                            //GoLevelUp();
                            GoRoot(_Settings.DataSource, _Settings.Filter, _DrawingBox);
                            if (_Settings.CanNavigate)
                                SetRendererBreadCrumb(_Settings.DataSource, _Settings.Filter, null, cMenuConfigReader.DataSources.GetData(_Settings.DataSource, _Settings.Filter));
                            break;
                    }
                    
                }                        

            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Error on select MenuItem!", Ex, true, EMessageTypes.Error);
            }
        }

        void SetRendererBreadCrumb(string sDataSource, string sPath, MinimizeablePanel Panel, cStartmenuItem Item)
        {
            try
            {
                string[] sTestParts = null;

                if (sPath.Length > 0 && Item != null)
                {
                    sTestParts = sPath.Split(new Char[] { '\\' });

                    StackPanel myStackpanel = new StackPanel();
                    cStartmenuItem CurrentPathPart = Item;
                    string stmpFilter = "";
                    bool bIsFirstParth = true;

                    for (int iPathPartCounter = 0;iPathPartCounter < sTestParts.Count(); iPathPartCounter++)
                    {   
                        if (stmpFilter.Length != 0){
                            stmpFilter += @"\";
                        }

                        stmpFilter += sTestParts[iPathPartCounter];                        

                        if (iPathPartCounter == sTestParts.Count() - 1)
                        {
                            //current folder is only a label without any action

                            System.Windows.Controls.Label oLinkLabel = new System.Windows.Controls.Label();
                            oLinkLabel.Content = LanguageStrings.GetText(CurrentPathPart.ViewName);
                            oLinkLabel.Tag = CurrentPathPart.FolderMenuPath;

                            cStyleChanger.ApplyStyleToRegionBreadCrumb(oLinkLabel, _Settings.Name);

                            myStackpanel.Children.Add(oLinkLabel);

                            if (iPathPartCounter > 0)
                            {
                                CurrentPathPart = (cStartmenuItem)CurrentPathPart.Parent;
                            }
                        }
                        else
                        {
                            cStartmenuItem tmpParent = cMenuConfigReader.DataSources.GetData(sDataSource, stmpFilter);
                            ThemedControlsLibrary.LinkLabel myLinkLabel = new ThemedControlsLibrary.LinkLabel();
                            myLinkLabel.Content = LanguageStrings.GetText(tmpParent.ViewName) + " > ";
                            myLinkLabel.Tag = tmpParent.FolderMenuPath;

                            myLinkLabel.Click += OnBreadCrumbSelect;
                            myLinkLabel.LinkLabelBehavior = ThemedControlsLibrary.LinkLabelBehavior.NeverUnderline;

                            cStyleChanger.ApplyStyleToRegionBreadCrumb(myLinkLabel, _Settings.Name);

                            myStackpanel.Children.Add(myLinkLabel);
                        }
                    }

                    myStackpanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
                    myStackpanel.Margin = new Thickness(0, 0, 0, 0);
                    myStackpanel.Orientation = Orientation.Horizontal;

                    if (_Settings.RendererMethode == eRenderType.Groups)
                        Panel.CaptionContent = myStackpanel;
                    else
                    {
                        ((Label)_DrawingBox.Tag).Content = myStackpanel;
                    }
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Can't render Menu path!", Ex, true, EMessageTypes.Error);
            }
        }

        void OnBreadCrumbSelect(object sender, EventArgs e)
        {
            try
            {
                if (sender != null)
                {
                    MinimizeablePanel oMinimizeablePanel = null;
                    string sDataSource = "";
                    string sFolderPath = (string)((ThemedControlsLibrary.LinkLabel)sender).Tag;

                    if (_Settings.RendererMethode == eRenderType.Groups)
                    {
                        oMinimizeablePanel = (MinimizeablePanel)((Grid)((Label)((StackPanel)((ThemedControlsLibrary.LinkLabel)sender).Parent).Parent).Parent).Parent;
                        sDataSource = ((WMSSoft.Lib.WinKStart.Model.MenuConfig.MinimizeablePanel)oMinimizeablePanel.Tag).DataSource;
                        cStartmenuItem tmpSelected = cMenuConfigReader.DataSources.GetData(sDataSource, sFolderPath);
                        RenderItems(tmpSelected, oMinimizeablePanel.ListContent);

                        SetRendererBreadCrumb(sDataSource, sFolderPath, oMinimizeablePanel, tmpSelected);
                    }
                    else
                    {
                        //render mode simple
                        sDataSource = _Settings.DataSource;
                        cStartmenuItem tmpSelected = cMenuConfigReader.DataSources.GetData(sDataSource, sFolderPath);
                        RenderItems(tmpSelected, _DrawingBox, eRenderType.Simple);
                        SetRendererBreadCrumb(sDataSource, sFolderPath, null, tmpSelected);
                    }
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Error while selecting Item Parent!", Ex, true, EMessageTypes.Error);
            }
        }

        void OnShowContextMenu(object sender, cStartmenuItem SelectedItem)
        {
            try
            {
                if (_CanShowContextmenu == false) return;

                if (_VisibleItems != null && _DrawingBox != null && SelectedItem != null)
                {
                    cStartmenuItem myItem = SelectedItem; 

                    WMSSoft.Lib.Shell.Win32Point myMousePoint = new WMSSoft.Lib.Shell.Win32Point();

                    if (WMSSoft.Lib.Shell.ShellAPI.GetCursorPos(ref myMousePoint) == true)
                    {
                        if (cMenuConfigReader.GUIActionElements.ContainsKey("SelectedItem") == false)
                            cMenuConfigReader.GUIActionElements.Add("SelectedItem", SelectedItem);
                        else
                            cMenuConfigReader.GUIActionElements["SelectedItem"] = SelectedItem;

                        eContextMenuTarget ContextTargetType = eContextMenuTarget.Custom;

                        //First select drawing context-menu items
                        Dictionary<int,string> oContextMenuItems = new Dictionary<int,string>();
                        if (cMenuConfigReader.ContextMenuToParent.ContainsKey(_Settings.Name) == true)
                        {
                            
                            Dictionary<string, string>.KeyCollection tmpKeys = cMenuConfigReader.ContextMenuToParent[_Settings.Name].Keys;

                            if (tmpKeys != null)
                            {
                                foreach (string Key in tmpKeys)
                                {
                                    if (cMenuConfigReader.ContextMenuTargets.ContainsKey(Key) == true)
                                    {
                                        ContextTargetType = cMenuConfigReader.ContextMenuTargets[Key].TargetType;

                                        foreach (WMSSoft.Lib.WinKStart.Model.MenuConfig.cWinKStartContextMenuItem CustomItem in cMenuConfigReader.ContextMenuTargets[Key].CustomMenuItems)
                                        {
                                            oContextMenuItems.Add(CustomItem.MenuID,
                                                                  CustomItem.Caption);
                                        }
                                    }

                                }
                            }
                        }
                        //Get Handle from Applications Main Window
                        IntPtr windowHandle = new System.Windows.Interop.WindowInteropHelper(Application.Current.MainWindow).Handle;

                        _RunCounter = 0; 
                        if (ContextTargetType == eContextMenuTarget.SelectedItem)
                        {
                            if (myItem.ItemType == eItemType.Link)
                            {
                                WMSSoft.Lib.Shell.Shell_helpers.ContextMenuActivated += ContextMenuIsActivated;
                                WMSSoft.Lib.Shell.Shell_helpers.ShowContextMenu(myItem.ItemName,
                                                                                windowHandle, //Handle from Applications Main Window
                                                                                myMousePoint.x,
                                                                                myMousePoint.y,
                                                                                oContextMenuItems); //ContextMenu - Items defined in Content.xml
                            }
                            else if (myItem.ItemType == eItemType.Folder)
                            {
                                string sFolderPath = "";
                                if (System.IO.Directory.Exists(System.IO.Path.Combine(myItem.UserStartMenuPath, myItem.FolderPath)) == true)
                                    sFolderPath = System.IO.Path.Combine(myItem.UserStartMenuPath, myItem.FolderPath);
                                else
                                    sFolderPath = System.IO.Path.Combine(myItem.AllUsersStartMenuPath, myItem.FolderPath);

                                WMSSoft.Lib.Shell.Shell_helpers.ShowContextMenu(sFolderPath, windowHandle, myMousePoint.x, myMousePoint.y);
                            }
                        }
                        else
                        {
                            //Custom - ContextMenu
                            if (oContextMenuItems.Count > 0)
                            {
                                //view only a Contextmenu if here are MenuItems
                                WMSSoft.Lib.Shell.Shell_helpers.ContextMenuActivated += ContextMenuIsActivated;
                                WMSSoft.Lib.Shell.Shell_helpers.ShowCustomContextMenu(windowHandle, //Handle from Applications Main Window
                                                                                      myMousePoint.x,
                                                                                      myMousePoint.y,
                                                                                      oContextMenuItems);
                            }
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Error on Show ContextMenu!", Ex, true, EMessageTypes.Error);
            }
        }

        void ContextMenuIsActivated(string File, int LinkType)
        {
            try
            {
                if (_RunCounter == 0)
                {
                    _RunCounter++;
                    if (cMenuConfigReader.ContextMenuIDToName.ContainsKey(LinkType) == true)
                    {
                        string sContextMenuItemName = cMenuConfigReader.ContextMenuIDToName[LinkType];

                        if (cMenuConfigReader.EventSourceToActionName.ContainsKey(sContextMenuItemName) == true)
                        {
                            string sActionName = cMenuConfigReader.EventSourceToActionName[sContextMenuItemName];
                            if (cMenuConfigReader.Actions.ContainsKey(sActionName) == true)
                            {
                                Dictionary<string, object> oFunctionParameters = new Dictionary<string, object>();

                                cWinKStartAction tmpAction = cMenuConfigReader.Actions[sActionName];
                                if (tmpAction != null)
                                {
                                    //On ContextMenu - Item only the Click Event is running
                                    if (tmpAction.Triggers["Click"].Event == eTriggerEvent.Click)
                                    {
                                        foreach (SourceElement SourceElement in tmpAction.SourceElements)
                                        {
                                            if (cMenuConfigReader.GUIActionElements.ContainsKey(SourceElement.Element) == true)
                                            {

                                                if (cMenuConfigReader.GUIActionElements[SourceElement.Element].GetType() == typeof(cStartmenuItem))
                                                {
                                                    //Now we Extract the in String given Property-name from the in Element given object name
                                                    _PropertyInfo prop = cMenuConfigReader.GUIActionElements[SourceElement.Element].GetType().GetProperty(SourceElement.Property);
                                                    object oValue = (object)prop.GetValue(cMenuConfigReader.GUIActionElements[SourceElement.Element], null);
                                                    //Add SourceElement to FunctionParameters
                                                    if (oFunctionParameters.ContainsKey(SourceElement.Property) == false)
                                                        oFunctionParameters.Add(SourceElement.Property, oValue);

                                                }
                                            }
                                        }

                                        //Run Function
                                        if (cMenuConfigReader.FunctionsReader.ItemInstances.ContainsKey(tmpAction.Function) == true)
                                            cMenuConfigReader.FunctionsReader.ItemInstances[tmpAction.Function].Run(oFunctionParameters);
                                    }
                                    else
                                    {
                                        CMessagelogging.AppendMessage("On ContextMenu - Items only the Click Event will work!", null, true, EMessageTypes.Error);
                                    }
                                }
                            }
                        }

                    }
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Error on Click ContextMenu!", Ex, true, EMessageTypes.Error);
            }
        }

        void Shell_helpers_AddFavorite(string File, int LinkType)
        {
            if (this.AddFavorite != null) this.AddFavorite(File, LinkType);            
        }

        void Shell_helpers_RemoveFavorite(string File, int LinkType)
        {
            if (this.RemoveFavorite != null) this.RemoveFavorite(File, LinkType);
        }

        /// <summary>
        /// Methode to select an Item (Link or Folder) or show Contextmenu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnSelectionMouseDown(object sender, MouseButtonEventArgs e)
        {
            try
            {


                cStartmenuItem SelectedItem = null;
                    //Read from current selected listboxitem the cStartMenuItem
                    System.Windows.Controls.ListBoxItem sourceItem = ((System.Windows.Controls.ListBoxItem)sender);
                    if (sourceItem != null)
                    {
                        if (sourceItem.Tag != null && sourceItem.Tag.GetType() == typeof(cStartmenuItem))
                        {
                            SelectedItem = (cStartmenuItem)sourceItem.Tag;
                        }

                        System.Windows.Controls.ListBox sourceParent = ((System.Windows.Controls.ListBox)sourceItem.Parent);
                        sourceParent.SelectedIndex = -1;
                    }
                    if (e.ChangedButton == MouseButton.Left)
                    {
                        OnSelectionChanged(((System.Windows.Controls.ListBox)sourceItem.Parent), SelectedItem);
                    }
                    else if (e.ChangedButton == MouseButton.Right)
                    {
                        //Show FileObject Shell - Contextmenu
                        OnShowContextMenu(((System.Windows.Controls.ListBox)sourceItem.Parent), SelectedItem);
                    }
                //clear SelectedItem
                _DrawingBox.SelectedIndex = -1;
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Error on ouseoperation!", Ex, true, EMessageTypes.Error);
            }
        }


        int AddItemToListBox(cStartmenuItem SubItem, ListBox Box, Dictionary<int, cStartmenuItem> VProgramItems)
        {
            try
            {
                if (SubItem != null)
                {
                    int iNewItemIndex = -1;                    

                    StackPanel myStackpanel = new StackPanel();
                    TextBlock myTextblock = new TextBlock();

                    //only a image is available we can add this
                    if (SubItem.Image != null)
                    {
                        Image myImage = new Image();
                        myImage.Height = 32;
                        myImage.Width = 32;
                        System.Windows.Media.Imaging.BitmapImage tmpImgb = SubItem.Image;

                        myImage.Source = tmpImgb;
                        myImage.Margin = new Thickness(5.0, 0.0, 0.0, 0.0);
                        myStackpanel.Children.Add(myImage);
                    }
                    else if (SubItem.ItemIcon != null)
                    {
                        Image myImage = new Image();
                        myImage.Height = 32;
                        myImage.Width = 32;
                        System.Windows.Media.Imaging.BitmapImage tmpImgb = basic_GraphicHelpers.GetWPFImageFromIcon(SubItem.ItemIcon);            

                        myImage.Source = tmpImgb;
                        myImage.Margin = new Thickness(5.0, 0.0, 0.0, 0.0);
                        myStackpanel.Children.Add(myImage);
                    }

                    myTextblock.TextAlignment = SubItem.TextAlign; 
                    myTextblock.Text = WMSSoft.Lib.Basic.LanguageStrings.GetText(SubItem.ViewName);
                    myTextblock.FontFamily = Box.FontFamily;
                    myTextblock.FontSize = Box.FontSize;
                    myTextblock.Foreground = Box.Foreground;
                    myTextblock.VerticalAlignment = Box.VerticalContentAlignment;                 
                    myTextblock.Padding = new Thickness(5.0, 0.0, 0.0, 0.0);                    
                   

                    myStackpanel.Children.Add(myTextblock);
                    myStackpanel.Height = SubItem.ItemHeight;
                    myStackpanel.Orientation = Orientation.Horizontal;
                    

                    ListBoxItem myListItem = new ListBoxItem();
                    myListItem.Content = myStackpanel;
                    myListItem.MouseUp += OnSelectionMouseDown;
                    
                    myListItem.Tag = SubItem;
                    iNewItemIndex = Box.Items.Add(myListItem);

                    if (iNewItemIndex >= 0 && iNewItemIndex < Box.Items.Count)
                    {
                        //add this item to programitem list
                        if (VProgramItems.ContainsKey(iNewItemIndex) == false)
                        {
                            VProgramItems.Add(iNewItemIndex, SubItem);
                        }
                    }
                    return iNewItemIndex;
                } return -1;
            }
            catch (Exception ex)
            {
                CMessagelogging.AppendMessage("Error while adding startmenuitem to listview!", ex, true, EMessageTypes.Error);
                return -1;
            }
        }

        /// <summary>
        /// Adds a label Item to Shutdownlistbox
        /// </summary>
        /// <param name="SubItem">Item to add</param>
        /// <returns>index with item position</returns>
        int AddLabelItemToListBox(cStartmenuItem SubItem, ListBox Box)
        {
            try
            {
                if (SubItem != null)
                {
                    int iNewItemIndex = -1;
                    TextBlock myTextblock = new TextBlock();
                    myTextblock.Text = WMSSoft.Lib.Basic.LanguageStrings.GetText(SubItem.ViewName);
                    myTextblock.Width = Box.Width - 35;
                    myTextblock.VerticalAlignment = SubItem.VerticalAlign; 
                    myTextblock.TextAlignment = SubItem.TextAlign; 
                    myTextblock.FontFamily = new System.Windows.Media.FontFamily(SubItem.FontName);
                    myTextblock.FontSize = SubItem.FontSize; 
                    myTextblock.Foreground = new SolidColorBrush(SubItem.FontColor); 
                    myTextblock.IsEnabled = false;

                    StackPanel myStackpanel = new StackPanel();
                    myStackpanel.Children.Add(myTextblock);
                    myStackpanel.Height = SubItem.ItemHeight;
                    myStackpanel.Orientation = Orientation.Horizontal;

                    ListBoxItem myListItem = new ListBoxItem();
                    myListItem.Content = myStackpanel;

                    iNewItemIndex = Box.Items.Add(myListItem);
                    ((ListBoxItem)Box.Items[iNewItemIndex]).IsEnabled = false;

                    return iNewItemIndex;
                }
                else return -1;
            }
            catch (Exception ex)
            {
                CMessagelogging.AppendMessage("Error while adding ShutdownLabelItem to listview!", ex, true, EMessageTypes.Error);
                return -1;
            }
        }

        #endregion
    }
}
